<?php

declare(strict_types=1);

namespace MultiWorker\Logger\Channel;

use Closure;
use MultiWorker\Logger\Channel;

class File extends Channel
{

    /**
     * 默认的日志名称
     * 
     * @var string
     */
    const LOG_NAME = 'multi-worker';

    /**
     * 日志文件后缀
     * 
     * @var string
     */
    const LOG_SUFFX = '.log';

     /**
     * 写日志
     *
     * @param string $message
     * @param mixed $level
     * @param array $context
     * @return void
     */
    public function write ($message,$level,array $context = [])
    {
        $content = $this->formatContent($message,$level,$context);
        if (!$this->isApartLevel($level)) {
            return;
        }
        $filename = $this->check();
        file_put_contents($filename,$content,FILE_APPEND);
    }

    /**
     * check file name.
     *
     * @return string
     */
    protected function check (): string
    {
        $maxSize  = $this->getConfig('file_size',-1);
        $filename = $this->getFileName();
        // 清除一下缓存
        clearstatcache();
        $fileSize = filesize($filename) / 1024;
        if ($maxSize != -1 && $fileSize > $maxSize) {
            $filename = $this->backup($filename);
        }
        return $filename;
    }

    /**
     * 备份文件返回新文件名称
     *
     * @param string $filename
     * @return string
     */
    protected function backup ($filename): string
    {
        $newFileName = $this->getFileName(true,false);
        rename($filename,$newFileName);
        return $filename;
    }

    /**
     * 获取日志文件名称
     *
     * @param boolean $rand
     * @param boolean $create
     * @return string
     */
    protected function getFileName ($rand = false,$create = true): string
    {
        $filename = $this->getConfig('filename',self::LOG_NAME);
        $filename = $filename instanceof Closure ? $filename() : $filename;
        if ($rand) {
            $filename .= '-' . time();
        }
        $path = $this->getConfig('path','') . DIRECTORY_SEPARATOR . $filename . self::LOG_SUFFX;
        is_dir(dirname($path)) || mkdir(dirname($path),0755,true);
        if ($create && !file_exists($path)) {
            touch($path);
        }
        return $path;
    }
}